package gdconf

import (
	"fmt"
	"server_cluster/common/logger"
)

// 角色天赋效果组配置表

// 效果修改器类型
const (
	EffectModifierTypeChangeDamagePercentage = 1 // 修改伤害倍率
	EffectModifierTypeChangeBuffId           = 2 // 修改buff
	EffectModifierTypeChangeBuffLayer        = 3 // 修改buff层数
	EffectModifierTypeChangeTempProp         = 4 // 修改临时属性
	EffectModifierTypeChangeParam4           = 5 // 修改吸血倍率
	EffectModifierTypeChangeParam5           = 6 // 修改韧性值伤害
	EffectModifierTypeAddSkillEffect         = 7 // 新增技能效果
	EffectModifierTypeAddDamageByBuffCount   = 8 // 按照buff层数增加伤害
	EffectModifierTypeAddDamageByTargetState = 9 // 按照目标状态增加伤害
)

type EffectModifierType int32

func (e EffectModifierType) String() string {
	switch e {
	case EffectModifierTypeChangeDamagePercentage:
		return "EffectModifierTypeChangeDamagePercentage"
	case EffectModifierTypeChangeBuffId:
		return "EffectModifierTypeChangeBuffId"
	case EffectModifierTypeChangeBuffLayer:
		return "EffectModifierTypeChangeBuffLayer"
	case EffectModifierTypeChangeTempProp:
		return "EffectModifierTypeChangeTempProp"
	case EffectModifierTypeChangeParam4:
		return "EffectModifierTypeChangeParam4"
	case EffectModifierTypeChangeParam5:
		return "EffectModifierTypeChangeParam5"
	case EffectModifierTypeAddSkillEffect:
		return "EffectModifierTypeAddSkillEffect"
	case EffectModifierTypeAddDamageByBuffCount:
		return "EffectModifierTypeAddDamageByBuffCount"
	case EffectModifierTypeAddDamageByTargetState:
		return "EffectModifierTypeAddDamageByTargetState"
	default:
		return ""
	}
}

type EffectModifier struct {
	ModifierType EffectModifierType // 效果修改器类型
	SkillId      int32              // 技能id
	EffectId     int32              // 效果id
	ParamIndex   int32              // 参数组索引
	Key          int32              // 键
	Value        int32              // 值
	Group        []int32            // 替换buff组
}

type RoleTalentEffectGroupConfig struct {
	EffectGroup        int32              `csv:"Group" gorm:"primary_key;autoIncrement:false"`           // 效果组
	Level              int32              `csv:"Level,omitempty" gorm:"primary_key;autoIncrement:false"` // 等级
	NeedPromote        int32              `csv:"Stage,omitempty"`                                        // 需要升阶阶段
	CostItem           *Item              `csv:"Cost,omitempty"`                                         // 消耗道具列表
	EffectModifierType EffectModifierType `csv:"ModifieType,omitempty"`                                  // 效果修改器类型
	Effect             IntArrayArray      `csv:"Effect,omitempty"`                                       // 效果
	FightPropAddList   FightPropAddList   `csv:"AddAttribute,omitempty"`                                 // 增加战斗属性列表

	EffectModifierList []*EffectModifier `gorm:"-" csv:"-"` // 效果修改器列表
}

func (rteg *RoleTalentEffectGroupConfig) TableName() string {
	return "config_role_talent_effect_group"
}

func (g *GameDataConfig) saveRoleTalentEffectGroupConfig() {
	saveTableToDb[RoleTalentEffectGroupConfig](g.Db, readTable[RoleTalentEffectGroupConfig](g.CsvPathPrefix+"role_talentGroup.csv"))
}

func (g *GameDataConfig) loadRoleTalentEffectGroupConfig() {
	g.GameDataMaps.RoleTalentEffectGroupConfigMap = make(map[int32]map[int32]*RoleTalentEffectGroupConfig)
	for _, roleTalentEffectGroupConfig := range loadTableFromDb[RoleTalentEffectGroupConfig](g.Db) {
		_, exist := g.GameDataMaps.RoleTalentEffectGroupConfigMap[roleTalentEffectGroupConfig.EffectGroup]
		if !exist {
			g.GameDataMaps.RoleTalentEffectGroupConfigMap[roleTalentEffectGroupConfig.EffectGroup] = make(map[int32]*RoleTalentEffectGroupConfig)
		}
		roleTalentEffectGroupConfig.EffectModifierList = make([]*EffectModifier, 0)
		if roleTalentEffectGroupConfig.Effect != nil {
			for k, array := range roleTalentEffectGroupConfig.Effect {
				switch roleTalentEffectGroupConfig.EffectModifierType {
				case EffectModifierTypeChangeDamagePercentage:
					if len(array) < 3 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						ParamIndex:   array[1] - 1,
						Value:        array[2],
					})
				case EffectModifierTypeChangeBuffId:
					if len(array) < 3 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						ParamIndex:   array[1] - 1,
						Group:        array[2:],
					})
				case EffectModifierTypeChangeBuffLayer:
					if len(array) < 3 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						ParamIndex:   array[1] - 1,
						Value:        array[2],
					})
				case EffectModifierTypeChangeTempProp:
					if len(array) < 3 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						Key:          array[1],
						Value:        array[2],
					})
				case EffectModifierTypeChangeParam4:
					if len(array) < 2 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						Value:        array[1],
					})
				case EffectModifierTypeChangeParam5:
					if len(array) < 2 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						Value:        array[1],
					})
				case EffectModifierTypeAddSkillEffect:
					if len(array) < 2 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						SkillId:      array[0],
						EffectId:     array[1],
					})
				case EffectModifierTypeAddDamageByBuffCount:
					if len(array) < 2 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						Value:        array[1],
					})
				case EffectModifierTypeAddDamageByTargetState:
					if len(array) < 2 {
						logger.Error("array is not match, groupId is %v,level is %v,idx is %v",
							roleTalentEffectGroupConfig.EffectGroup, roleTalentEffectGroupConfig.Level, k)
						continue
					}
					roleTalentEffectGroupConfig.EffectModifierList = append(roleTalentEffectGroupConfig.EffectModifierList, &EffectModifier{
						ModifierType: roleTalentEffectGroupConfig.EffectModifierType,
						EffectId:     array[0],
						Value:        array[1],
					})
				default:
					info := fmt.Sprintf("unknown effect modifier type: %v", roleTalentEffectGroupConfig.EffectModifierType)
					panic(info)
				}
			}
		}
		g.GameDataMaps.RoleTalentEffectGroupConfigMap[roleTalentEffectGroupConfig.EffectGroup][roleTalentEffectGroupConfig.Level] = roleTalentEffectGroupConfig
	}
	logger.Info("RoleTalentEffectGroupConfig Count: %v", len(g.GameDataMaps.RoleTalentEffectGroupConfigMap))
}

func GetRoleTalentEffectGroupConfigByGroupAndLevel(group int32, level int32) *RoleTalentEffectGroupConfig {
	value1, exist := CONF.GameDataMaps.RoleTalentEffectGroupConfigMap[group]
	if !exist {
		logger.Error("[ConfigNotFound] RoleTalentEffectGroupConfig, group: %v, level: %v", group, level)
		return nil
	}
	value2, exist := value1[level]
	if !exist {
		logger.Error("[ConfigNotFound] RoleTalentEffectGroupConfig, group: %v, level: %v", group, level)
		return nil
	}
	return value2
}

func GetRoleTalentEffectGroupConfigMap() map[int32]map[int32]*RoleTalentEffectGroupConfig {
	return CONF.GameDataMaps.RoleTalentEffectGroupConfigMap
}
